package com.wwdx.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.google.common.collect.Maps;
import com.wwdx.model.WwdxPersonalModel;
import com.wwdx.model.WwdxVipUserModel;
import com.wwdx.model.WwdxWeixinUserModel;
import com.wwdx.model.dto.PersonalDTO;
import com.wwdx.service.WwdxPersonalServiceI;
import com.wwdx.utils.ConstantHolder;
import com.wwdx.utils.jackson.JsonUtils;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author liguoliang
 * @date 2017/11/5.
 */
@Service
public class WwdxPersonalServiceImpl extends BaseServiceImpl<WwdxPersonalModel> implements WwdxPersonalServiceI {

    @Override
    public Long selectModelCount(WwdxPersonalModel model) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(4);
        String hql = "select count(1) from WwdxPersonalModel\t"+getParams(model,params);
        return this.count(hql,params);
    }

    private String getParams(WwdxPersonalModel model, Map<String, Object> params){
        StringBuilder sb = new StringBuilder("where 1=1\n");
        Long userid = model.getUserid();
        if (userid != null){
            sb.append("and userid=:userid\n");
            params.put("userid",userid);
        }
        String nickname = model.getNickname();
        if (StringUtils.isNotBlank(nickname)){
            sb.append("and nickname like :nickname\n");
            params.put("nickname","%"+nickname+"%");
        }
        Integer white = model.getWhite();
        if (white != null){
            sb.append("and white=:white\n");
            params.put("white",white);
        }
        return sb.toString();
    }

    @Override
    public List<WwdxPersonalModel> selectModelList(WwdxPersonalModel model, Integer page, Integer rows) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(4);
        String hql = "from WwdxPersonalModel\t"+getParams(model,params)+"\torder by gmtCreated desc";
        return this.find(hql, params, page, rows);
    }

    @Override
    public WwdxPersonalModel getByUnionid(String unionid) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(2);
        params.put("unionid",unionid);
        return getByHql("from WwdxPersonalModel where unionId=:unionid",params);
    }

    @Override
    public String getByToken(String token) {
        String key = String.format(ConstantHolder.USER_OBJ, token);
        return (String) valueOperations.get(key);
    }

    private String saveToken(String unionid) {
        String token = super.getUUID().toUpperCase();
        //通过token保存用户信息
        String key = String.format(ConstantHolder.USER_OBJ, token);
        valueOperations.set(key,unionid);
        //token有效期24小时
        redisTemplate.expire(key, 24 * 60 * 60, TimeUnit.SECONDS);
        //通过unionid保存token信息
        valueOperations.set(String.format(ConstantHolder.USER_TOKEN, unionid),token);
        return token;
    }

    private void execute(WwdxPersonalModel wwdxPersonalModel){
        String unionid = wwdxPersonalModel.getUnionId();
        //获取令牌
        String token = this.saveToken(unionid);
        wwdxPersonalModel.setToken(token);
        //会员
        WwdxVipUserModel wwdxVipUserModel = wwdxVipUserService.getByUnionId(unionid);
        if (wwdxVipUserModel != null){
            wwdxPersonalModel.setVip(wwdxVipUserModel);
        }
    }

    @Override
    public WwdxPersonalModel executePersonalInfo(WxMpUser wxMpUser, WxMpService service){
        logger.info("\n微信H5用户信息:{}", wxMpUser);
        String nickname = wxMpUser.getNickname(), headImgUrl = wxMpUser.getHeadImgUrl(),unionId = wxMpUser.getUnionId();
        Integer sex = wxMpUser.getSex();
        long userid;
        WwdxPersonalModel wwdxPersonalModel = this.getByUnionid(unionId);
        Date date = new Date();
        if (wwdxPersonalModel == null){
            wwdxPersonalModel = WwdxPersonalModel.builder()
                    .channel(ConstantHolder.Constant.WEIXIN).nickname(nickname).sex(sex).headImgUrl(headImgUrl).unionId(unionId)
                    .gmtCreated(date).gmtModified(date).build();
            userid = (long)save(wwdxPersonalModel);
            logger.info("新增用户：{}",userid);
            wwdxPersonalModel = super.getById(userid);
        }else{
            //已存在用户
            userid = wwdxPersonalModel.getUserid();
            logger.info("已存在用户：{}",userid);
            wwdxPersonalModel.setGmtModified(date);
            wwdxPersonalModel.setNickname(nickname);
            wwdxPersonalModel.setHeadImgUrl(headImgUrl);
            wwdxPersonalModel.setSex(sex);
            this.update(wwdxPersonalModel);
        }
        String openId = wxMpUser.getOpenId();
        //检测登录用户是否关注公众号
        boolean subscribe = false;
        WwdxWeixinUserModel wwdxWeixinUserModel = wwdxWeixinUserService.getByOpenId(openId);
        if (wwdxWeixinUserModel != null){
            subscribe = true;
        }
        wwdxPersonalModel.setSubscribe(subscribe);
        wwdxPersonalModel.setOpenId(openId);
        this.execute(wwdxPersonalModel);
        return wwdxPersonalModel;
    }

    @Override
    public WwdxPersonalModel executePersonalInfo(WxMaUserInfo wxMaUserInfo, WxMaService service){
        logger.info("\n微信小程序用户信息:{}", JsonUtils.bean2Json(wxMaUserInfo));
        String nickname = wxMaUserInfo.getNickName(), headImgUrl = wxMaUserInfo.getAvatarUrl(),unionId = wxMaUserInfo.getUnionId();
        Integer sex = Integer.valueOf(wxMaUserInfo.getGender());
        long userid;
        WwdxPersonalModel wwdxPersonalModel = this.getByUnionid(unionId);
        Date date = new Date();
        if (wwdxPersonalModel == null){
            wwdxPersonalModel = WwdxPersonalModel.builder()
                    .channel(ConstantHolder.Constant.WXMA).nickname(nickname).sex(sex).headImgUrl(headImgUrl).unionId(unionId)
                    .gmtCreated(date).gmtModified(date).build();
            userid = (long)save(wwdxPersonalModel);
            logger.info("新增用户：{}",userid);
            wwdxPersonalModel = super.getById(userid);
        }else{
            //已存在用户
            userid = wwdxPersonalModel.getUserid();
            logger.info("已存在用户：{}",userid);
            wwdxPersonalModel.setNickname(nickname);
            wwdxPersonalModel.setSex(sex);
            wwdxPersonalModel.setHeadImgUrl(headImgUrl);
            wwdxPersonalModel.setGmtModified(date);
            this.update(wwdxPersonalModel);
        }
        wwdxPersonalModel.setOpenId(wxMaUserInfo.getOpenId());
        this.execute(wwdxPersonalModel);
        return wwdxPersonalModel;
    }

    @Override
    public WwdxPersonalModel executePersonalInfo(String phone) {
        logger.info("\n手机验证码登录:{}", phone);
        String headImgUrl = "headimg.jpg", nickname = "用户"+System.currentTimeMillis() / 1000;
        long userid;
        WwdxPersonalModel wwdxPersonalModel = this.getByUnionid(phone);
        Date date = new Date();
        if (wwdxPersonalModel == null){
            wwdxPersonalModel = WwdxPersonalModel.builder()
                    .channel(ConstantHolder.Constant.IOS).nickname(nickname).headImgUrl(headImgUrl).unionId(phone)
                    .gmtCreated(date).gmtModified(date).build();
            userid =(long)save(wwdxPersonalModel);
            logger.info("新增用户：{}",userid);
            wwdxPersonalModel = super.getById(userid);
        }else {
            //已存在用户
            userid = wwdxPersonalModel.getUserid();
            logger.info("已存在用户：{}",userid);
            wwdxPersonalModel.setGmtModified(date);
            this.update(wwdxPersonalModel);
        }
        this.execute(wwdxPersonalModel);
        return wwdxPersonalModel;
    }

    @Override
    public WwdxPersonalModel executePersonalInfo(PersonalDTO model) {
        logger.info("\nAPP微信用户信息:{}", model);
        String channel = model.getChannel() == null ? ConstantHolder.Constant.ANDROID : model.getChannel();
        String nickname = model.getNickname(),headImgUrl = model.getHeadimgurl(),unionid = model.getUnionid();
        Integer sex = model.getSex();
        long userid;
        WwdxPersonalModel wwdxPersonalModel = this.getByUnionid(unionid);
        Date date = new Date();
        if (wwdxPersonalModel == null){
            wwdxPersonalModel = WwdxPersonalModel.builder()
                    .channel(channel).nickname(nickname).sex(sex).headImgUrl(headImgUrl).unionId(unionid)
                    .gmtCreated(date).gmtModified(date).build();
            userid = (long)save(wwdxPersonalModel);
            logger.info("新增用户：{}",userid);
            wwdxPersonalModel = super.getById(userid);
        }else {
            //已存在用户
            userid = wwdxPersonalModel.getUserid();
            logger.info("已存在用户：{}",userid);
            wwdxPersonalModel.setNickname(nickname);
            wwdxPersonalModel.setHeadImgUrl(headImgUrl);
            wwdxPersonalModel.setSex(sex);
            wwdxPersonalModel.setGmtModified(date);
            this.update(wwdxPersonalModel);
        }
        this.execute(wwdxPersonalModel);
        return wwdxPersonalModel;
    }

    /**
     * 清空白名单
     */
    @Override
    public void getWhiteList(Long userid){
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(2);
        String unionid = this.getById(userid).getUnionId();
        params.put("unionid",unionid);

        //删除订单记录
        String hql = "from WwdxOrderModel where unionid=:unionid";
        wwdxOrderService.find(hql,params).forEach(wwdxOrderService::delete);

        //删除优惠卷记录
        hql = "from WwdxCouponLogModel where unionid=:unionid";
        wwdxCouponLogService.find(hql, params).forEach(wwdxCouponLogService::delete);

        //删除虚拟币
        hql = "from WvirtualUserModel where unionid=:unionid";
        wvirtualUserService.find(hql,params).forEach(wvirtualUserService::delete);

        //删除兑换码记录
        hql = "from WwdxCdKeyModel where unionid=:unionid";
        wwdxCdKeyService.find(hql,params).forEach(wwdxCdKeyService::delete);

        params.clear();
        params.put("userid",userid);

        //删除小D问题
        hql = "from WwdxXiaodModel where userid=:userid";
        wwdxXiaodService.find(hql, params).forEach(wwdxXiaodService::delete);

        //删除评论
        hql = "from WwdxCommentModel where userid=:userid";
        wwdxCommentService.find(hql, params).forEach(wwdxCommentService::delete);

        //删除会员
        wwdxVipUserService.delete(wwdxVipUserService.getByUnionId(unionid));
        //删除已购买记录
        redisTemplate.delete(String.format(ConstantHolder.USER_PURCHASE_MAP,unionid));
        //删除书架
        redisTemplate.delete(String.format(ConstantHolder.USER_BOOKSHELF_MAP,unionid));
        //删除用户令牌
        redisTemplate.delete(String.format(ConstantHolder.USER_TOKEN,unionid));
    }
}